package com.keba.basic.database.column;

import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import com.keba.basic.database.plugins.EncryptInterceptor;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Repository;
import com.keba.basic.context.ContextUtil;
import com.keba.basic.database.config.BaseMybatisConfiguration;
import com.keba.basic.database.properties.DatabaseProperties;
import com.keba.lamp.datascope.interceptor.DataScopeInnerInterceptor;

import java.util.ArrayList;
import java.util.List;

import static com.keba.lamp.common.constant.BizConstant.BUSINESS_PACKAGE;
import static com.keba.lamp.common.constant.BizConstant.UTIL_PACKAGE;

/**
 * Mybatis 常用重用拦截器，lamp.database.multiTenantType=任意模式 都需要实例出来
 * <p>
 * 拦截器执行一定是：
 * WriteInterceptor > DataScopeInterceptor > PaginationInterceptor
 *
 * @author zuihou
 * @date 2018/10/24
 */
@Configuration
@Slf4j
@EnableConfigurationProperties({DatabaseProperties.class})
@MapperScan(basePackages = {UTIL_PACKAGE, BUSINESS_PACKAGE}, annotationClass = Repository.class)
public class MybatisAutoConfiguration extends BaseMybatisConfiguration {

    public MybatisAutoConfiguration(final DatabaseProperties databaseProperties) {
        super(databaseProperties);
    }

    /**
     * COLUMN 模式 SQL动态拼接拦截器
     *
     * @return 插件
     */
    @Override
    protected List<InnerInterceptor> getPaginationBeforeInnerInterceptor() {
        List<InnerInterceptor> list = new ArrayList<>();
        // COLUMN 模式 多租户插件
        TenantLineInnerInterceptor tli = new TenantLineInnerInterceptor();
        tli.setTenantLineHandler(new TenantLineHandler() {
            @Override
            public String getTenantIdColumn() {
                return databaseProperties.getTenantIdColumn();
            }

            @Override
            public boolean ignoreTable(String tableName) {
                if (ContextUtil.isEmptyBasePoolNameHeader()) {
                    return true;
                }

                boolean ignoreTable = databaseProperties.getIgnoreTable() != null && databaseProperties.getIgnoreTable().contains(tableName);

                boolean ignoreTablePrefix = databaseProperties.getIgnoreTablePrefix() != null &&
                        databaseProperties.getIgnoreTablePrefix().stream().anyMatch(prefix -> tableName.startsWith(prefix));
                return ignoreTable || ignoreTablePrefix;
            }


            @Override
            public Expression getTenantId() {
                return new LongValue(ContextUtil.getBasePoolNameHeader());
            }
        });
        list.add(tli);

        Boolean isDataScope = databaseProperties.getIsDataScope();
        if (isDataScope) {
            list.add(getDataScopeInnerInterceptor());
        }

        return list;
    }


    @Override
    protected List<InnerInterceptor> getPaginationAfterInnerInterceptor() {
        List<InnerInterceptor> list = new ArrayList<>();
        list.add(getOptimisticLockerInnerInterceptor());
        return list;
    }

    @Bean
    public DataScopeInnerInterceptor getDataScopeInnerInterceptor() {
        return new DataScopeInnerInterceptor();
    }

    @Bean
    public OptimisticLockerInnerInterceptor getOptimisticLockerInnerInterceptor() {
        return new OptimisticLockerInnerInterceptor();
    }


}
